在 ClickHouse 的高性能查詢背後,除了列式儲存與向量化執行外,「壓縮技術」與「資料跳過索引(Data Skipping Indexes)」也是讓它能夠應對 PB 級資料的核心關鍵。本文將深入解析這兩項技術的原理與應用,並說明如何有效提升查詢效率、降低儲存成本。
One of the secrets to ClickHouse query performance is compression.
在 OLAP 場景中,資料量動輒百萬、千萬筆,若未經良好壓縮處理,磁碟 I/O 將成為查詢效率瓶頸。ClickHouse 採用 Columnar Storage,讓每欄資料型態一致、重複性高,使得壓縮成效極佳。
壓縮編碼 | 特性與應用說明 |
---|---|
LZ4 (預設) | 高速低延遲,壓縮比中等,預設壓縮器,適用即時查詢與寫入場景 |
ZSTD | 壓縮比高於 LZ4,但壓縮/解壓速度稍慢,適合冷資料儲存或報表分析 |
Delta Encoding | 對遞增數值(如時間戳、ID)進行差值壓縮,大幅減少儲存空間 |
Gorilla Encoding | 對時間序列數據極致優化,適用 IoT 與時序資料壓縮(例如 CPU 使用率、溫度等) |
Double Delta | 適用變化趨勢平穩的數值型資料,加強壓縮效果 |
以下是以 ClickHouse 儲存 StackOverflow posts 資料表的壓縮統計,透過查詢 system.columns
取得各欄位壓縮前後的體積與壓縮比資料
SELECT name,
formatReadableSize(sum(data_compressed_bytes)) AS compressed_size,
formatReadableSize(sum(data_uncompressed_bytes)) AS uncompressed_size,
round(sum(data_uncompressed_bytes) / sum(data_compressed_bytes), 2) AS ratio
FROM system.columns
WHERE table = 'posts'
GROUP BY name
┌─name──────────────────┬─compressed_size─┬─uncompressed_size─┬───ratio────┐
│ Body │ 46.14 GiB │ 127.31 GiB │ 2.76 │
│ Title │ 1.20 GiB │ 2.63 GiB │ 2.19 │
│ Score │ 84.77 MiB │ 736.45 MiB │ 8.69 │
│ Tags │ 475.56 MiB │ 1.40 GiB │ 3.02 │
│ ParentId │ 210.91 MiB │ 696.20 MiB │ 3.3 │
│ Id │ 111.17 MiB │ 736.45 MiB │ 6.62 │
│ AcceptedAnswerId │ 81.55 MiB │ 736.45 MiB │ 9.03 │
│ ClosedDate │ 13.99 MiB │ 517.82 MiB │ 37.02 │
│ LastActivityDate │ 489.84 MiB │ 964.64 MiB │ 1.97 │
│ CommentCount │ 37.62 MiB │ 565.30 MiB │ 15.03 │
│ OwnerUserId │ 368.98 MiB │ 736.45 MiB │ 2 │
│ AnswerCount │ 21.82 MiB │ 622.35 MiB │ 28.53 │
│ FavoriteCount │ 280.95 KiB │ 508.40 MiB │ 1853.02 │
│ ViewCount │ 95.77 MiB │ 736.45 MiB │ 7.69 │
│ LastEditorUserId │ 179.47 MiB │ 736.45 MiB │ 4.1 │
│ ContentLicense │ 5.45 MiB │ 847.92 MiB │ 155.5 │
│ OwnerDisplayName │ 14.30 MiB │ 142.58 MiB │ 9.97 │
│ PostTypeId │ 20.93 MiB │ 565.30 MiB │ 27 │
│ CreationDate │ 314.17 MiB │ 964.64 MiB │ 3.07 │
│ LastEditDate │ 346.32 MiB │ 964.64 MiB │ 2.79 │
│ LastEditorDisplayName │ 5.46 MiB │ 124.25 MiB │ 22.75 │
│ CommunityOwnedDate │ 2.21 MiB │ 509.60 MiB │ 230.94 │
└───────────────────────┴─────────────────┴───────────────────┴────────────┘
你會發現:
你可以在建表時,透過 CODEC
參數指定欄位使用的壓縮編碼:
CREATE TABLE user_events (
event_date Date,
user_id UInt32,
event_type String CODEC(ZSTD),
event_value Float64 CODEC(Delta, LZ4)
) ENGINE = MergeTree
PARTITION BY toYYYYMM(event_date)
ORDER BY (event_date, user_id);
event_type
使用 ZSTD,適合重複性高的字串欄位。event_value
使用 Delta 編碼處理數值,再以 LZ4 壓縮,提升查詢與儲存效能。Data Skipping Indexes(資料跳過索引) 是 ClickHouse 特有的查詢加速技術,核心原理是:
在查詢時,只掃描必要的資料區塊,跳過無關區塊,降低 I/O 成本與查詢延遲。
這些索引不是傳統意義上的 B-Tree 索引,而是針對 MergeTree 資料片段內的「欄位統計資訊」建立的快速過濾機制。
每個 MergeTree Part 會為主鍵欄位自動建立 minmax
索引,例如:
SELECT * FROM orders WHERE order_date >= '2025-01-01' AND order_date < '2025-02-01';
min(order_date)
~ max(order_date)
範圍。假設你有 10 億筆日誌資料:
這就是 Partition Pruning + Data Skipping 的效果。
ClickHouse 也允許你針對特定欄位建立進階索引,例如:
CREATE TABLE logs (
timestamp DateTime,
level String,
message String
) ENGINE = MergeTree
ORDER BY timestamp
SETTINGS index_granularity = 8192;
ALTER TABLE logs ADD INDEX idx_level (level) TYPE set(1000) GRANULARITY 1;
索引類型 | 說明與應用 |
---|---|
minmax |
預設,針對數值或日期範圍查詢加速 |
set(N) |
建立集合型索引,適用高重複字串欄位(如 Log Level) |
ngrambf_v1 |
適用模糊查詢,加上布隆過濾器實現快速匹配 |
bloom_filter |
快速過濾欄位可能值,適用多值欄位(如 tags、labels) |
index_granularity
預設為 8192 筆,查詢越頻繁、粒度可適當調小以加速跳過效率。ClickHouse 透過高效的壓縮與跳過索引技術,讓大數據查詢也能實現「ms級響應」。但記得不要濫用索引噢,反而會適得其反呢。